<template>
  <div class="calendar-container">
    <div class="calendar-header">
      <button @click="prevMonth">&lt;</button>
      <h2>{{ formattedDate }}</h2>
      <button @click="nextMonth">&gt;</button>
    </div>

    <div class="weekdays">
      <div v-for="day in ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']" :key="day">{{ day }}</div>
    </div>

    <div class="days-grid">
      <div 
        v-for="(day, index) in days" 
        :key="index"
        class="day"
        :class="{
          'current-month': day.isCurrentMonth,
          'checked': day.checked,
          [day.streakPosition]: day.checked,
          'today': day.isToday
        }"
        :style="{ 
          '--base-color': day.color,
          '--darker-color': day.darkerColor
        }"
        @click="toggleCheck(day)"
      >
        <div class="date-number">
          {{ day.date.getDate() }}
        </div>
      </div>
    </div>
    <div class="saying">
      <img class="lun" src="../assets/lun.png">
      <div class="title-dk">每日 打卡</div>
      <div class="content-dk">{{ dk }}</div>
      <img class="dk" src="../assets/dk.png">
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from 'vue'

const dk='打卡，是给自己的承诺；努力，是对未来的投资。'
// 配置参数
const colors = ['#d8bc92', '#ade5f2', '#f48cba', '#65e56e']
let colorIndex = ref(0)
let currentBaseColor = ref(colors[0])

// 状态管理
const currentDate = ref(new Date())
const records = ref({})

// 日期格式化
const formattedDate = computed(() => {
  const options = { 
    month: 'short', 
    day: 'numeric', 
    weekday: 'long' 
  }
  return currentDate.value.toLocaleDateString('en-US', options)
})

// 月份切换逻辑
const prevMonth = () => {
  const newDate = new Date(currentDate.value)
  newDate.setMonth(newDate.getMonth() - 1)
  currentDate.value = newDate
}

const nextMonth = () => {
  const newDate = new Date(currentDate.value)
  newDate.setMonth(newDate.getMonth() + 1)
  currentDate.value = newDate
}

// 颜色处理函数
const darkenColor = (color, amount = 15) => {
  const col = color.slice(1)
  const num = parseInt(col, 16)
  const r = Math.max(0, (num >> 16) - amount)
  const g = Math.max(0, (num >> 8 & 0x00FF) - amount)
  const b = Math.max(0, (num & 0x0000FF) - amount)
  return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, '0')}`
}

// 日历生成逻辑
const generateCalendar = () => {
  const year = currentDate.value.getFullYear()
  const month = currentDate.value.getMonth()
  const firstDay = new Date(year, month, 1)
  const lastDay = new Date(year, month + 1, 0)
  
  const days = []
  const startDay = firstDay.getDay()
  
  // 添加上月日期
  for (let i = startDay; i > 0; i--) {
    const date = new Date(year, month, -i + 1)
    days.push(createDayObject(date, false))
  }

  // 添加本月日期
  for (let i = 1; i <= lastDay.getDate(); i++) {
    const date = new Date(year, month, i)
    days.push(createDayObject(date, true))
  }

  // 添加下月日期
  const remaining = 35 - days.length
  for (let i = 1; i <= remaining; i++) {
    const date = new Date(year, month + 1, i)
    days.push(createDayObject(date, false))
  }

  return days
}

const createDayObject = (date, isCurrentMonth) => {
  const dateString = date.toISOString().split('T')[0]
  const today = new Date()
  const isToday = date.toDateString() === today.toDateString()
  
  const record = records.value[dateString] || {}
  return {
    date,
    isCurrentMonth,
    isToday,
    checked: record.checked || false,
    color: record.color || 'transparent',
    darkerColor: record.darkerColor || 'transparent',
    streakPosition: record.streakPosition || ''
  }
}

// 核心打卡逻辑
const toggleCheck = (day) => {
  if (!day.isCurrentMonth) return
  
  const dateString = day.date.toISOString().split('T')[0]
  const newChecked = !day.checked
  
  // 增强断签检测逻辑
  if (newChecked) {
    const lastDate = getLastCheckedDate()
    if (lastDate) {
      const daysDiff = calculateDaysDifference(lastDate, day.date)
      
      // 如果存在间隔天数，且不是连续的天数
      if (daysDiff > 1) {
        colorIndex.value = (colorIndex.value + 1) % colors.length
        currentBaseColor.value = colors[colorIndex.value]
      }
    } else if (Object.keys(records.value).length > 0) {
      // 如果存在历史记录但无最后日期（清理过数据的情况）
      colorIndex.value = (colorIndex.value + 1) % colors.length
      currentBaseColor.value = colors[colorIndex.value]
    }
  }

  // 生成颜色记录（强制使用最新颜色）
  const baseColor = newChecked ? currentBaseColor.value : 'transparent'
  const darkerColor = newChecked ? darkenColor(baseColor) : 'transparent'

  records.value[dateString] = {
    checked: newChecked,
    color: baseColor,
    darkerColor: darkerColor,
    streakPosition: ''
  }

  updateStreakStatus()
  saveToLocalStorage()
}

// 新增：精确计算天数差
const calculateDaysDifference = (prevDateStr, currentDate) => {
  const prevDate = new Date(prevDateStr)
  const timeDiff = currentDate.getTime() - prevDate.getTime()
  return Math.floor(timeDiff / (1000 * 3600 * 24))
}


// 连续区间处理
const updateStreakStatus = () => {
  const dates = Object.keys(records.value)
    .filter(k => records.value[k].checked)
    .sort()

  // 重置所有标记
  dates.forEach(dateStr => {
    records.value[dateStr].streakPosition = ''
  })

  let currentStreak = []
  let currentColor = null
  dates.forEach((dateStr, index) => {
    const prevDate = dates[index - 1]

    if (prevDate && isConsecutive(prevDate, dateStr)) {
      currentStreak.push(dateStr)
    } else {
      // 处理当前连击区间，并同步颜色
      processStreak(currentStreak, currentColor)
      currentStreak = [dateStr]
      currentColor = records.value[dateStr].color  // 记录颜色
    }
  })
  // 处理最后一个连击区间
  processStreak(currentStreak, currentColor)
}

const processStreak = (streak, color) => {
  if (streak.length === 0) return

  // 使用当前最新颜色覆盖旧颜色
  const currentColor = color || currentBaseColor.value
  const currentDarkerColor = darkenColor(currentColor)

  streak.forEach((dateStr, index) => {
    const position = getStreakPosition(streak.length, index)
    records.value[dateStr] = {
      ...records.value[dateStr],
      color: currentColor,
      darkerColor: currentDarkerColor,
      streakPosition: position
    }
  })
}


// 辅助函数
const getStreakPosition = (length, index) => {
  if (length === 1) return 'single'
  if (index === 0) return 'start'
  if (index === length - 1) return 'end'
  return 'middle'
}

const isConsecutive = (prev, curr) => {
  return new Date(prev).getTime() + 86400000 === new Date(curr).getTime()
}

const getLastCheckedDate = () => {
  const dates = Object.keys(records.value)
    .filter(k => records.value[k].checked)
    .sort()
  return dates.length > 0 ? dates[dates.length - 1] : null
}

// 数据持久化
const saveToLocalStorage = () => {
  const saveData = {
    records: records.value,
    colorIndex: colorIndex.value,
    currentBaseColor: currentBaseColor.value
  }
  localStorage.setItem('calendarData', JSON.stringify(saveData))
}

const loadFromLocalStorage = () => {
  const saved = localStorage.getItem('calendarData')
  if (saved) {
    const data = JSON.parse(saved)
    records.value = data.records || {}
    colorIndex.value = data.colorIndex || 0
    currentBaseColor.value = data.currentBaseColor || colors[0]
  }
}

// 计算属性和监听
const days = computed(generateCalendar)
const currentYear = computed(() => currentDate.value.getFullYear())
const currentMonth = computed(() => currentDate.value.getMonth())

watch(currentDate, () => {
  days.value = generateCalendar()
})

// 初始化
onMounted(() => {
  loadFromLocalStorage()
  updateStreakStatus()
})
</script>

<style scoped>
.calendar-container {
  max-width: 600px;
  margin: 20px auto;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  
}

.calendar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  border-bottom: 1px solid #434343; 
}

.calendar-header button {
  background: none;
  border: none;
  font-size: 1.5em;
  cursor: pointer;
  color: #666;
  padding: 0 15px;
}

.weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  margin-bottom: 5px;
  margin-top: 20px;
  font-weight: 500;
  color: #666;
}

.days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0;
  border-bottom: 1px solid #434343; 
  padding-bottom: 10px;
}

.day {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  margin-top: 5px;
  margin-bottom: 5px;
  cursor: pointer;
  transition: all 0.2s;
  z-index: 1;
}

.date-number {
  position: relative;
  z-index: 2;
  font-size: 14px;
  color: #333;
  pointer-events: none;
  text-shadow: 0 0 2px rgba(255,255,255,0.5);
}

/* 单个打卡 */
.day.checked.single {
  background: var(--darker-color) !important;
  border-radius: 15px;
}

/* 连续开始 */
.day.checked.start {
  background: var(--darker-color) !important;
  border-radius: 15px 0 0 15px;
}

/* 连续中间 */
.day.checked.middle {
  background: var(--base-color);
  opacity: 0.8;
}

/* 连续结束 */
.day.checked.end {
  background: var(--darker-color) !important;
  border-radius: 0 15px 15px 0;
}

/* 非当前月 */
.day:not(.current-month) .date-number {
  color: #999 !important;
  opacity: 0.7;
}

/* 悬停效果 */
.day:hover {
  transform: scale(1.1);
  z-index: 3;
  box-shadow: 0 0 8px rgba(0,0,0,0.1);
}

.day.checked .date-number {
  color: rgb(255, 255, 255) !important;
}

.day.today .date-number {
  position: relative;
  color: #2f61cd !important;
  font-weight: bold;
}

.day.today .date-number::after {
  content: '';
  position: absolute;
  bottom: -3px;
  left: 50%;
  transform: translateX(-50%);
  width: 18px;
  height: 2px;
  background-color: #2f61cd;
  border-radius: 1px;
}


.saying {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 85px;
  margin-top: 30px;
  background: rgba(0, 0, 0, 0.04);
  border-radius: 30px;
  position: relative;
}

.lun {
  position: absolute;
  left: 4%;
  top: 6%;
  width: 20px; 
  height: 20px; 
  object-fit: cover;
}

.title-dk {
  font-weight: bold;
  margin-top: 10px;
  font-family: 'Segoe UI';
  font-style: normal;
  font-weight: 400;
  font-size: 20px;
  line-height: 16px;
  align-items: center;
  color: #1ba3ff;
}

.content-dk {
  width: 200px;
  text-align: center;
  margin-top: 5px; 
  height: 40px;
  font-family: 'Segoe UI';
  font-style: normal;
  font-weight: 400;
  font-size: 16px;
  line-height: 20px;
  align-items: center;
  color: #1A1A1A;
}

.dk {
  position: absolute;
  width: 40px;
  height: 40px;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
}

</style>